// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) Cvitek Co., Ltd. 2019-2022. All rights reserved.
 *
 * File Name: jenc.c
 * Description:
 */

#ifdef FREERTOS_BSP
#include "stdint.h"
#include "types.h"
#include "csr.h"
#include "csi_rv64_gcc.h"
#include "core_rv64.h"
#include "arch_time.h"
#include "top_reg.h"
#include "jenc.h"
#include "delay.h"
#include "mmio.h"
#include "memmap.h"
#else
#include <linux/time.h>
#include <linux/uaccess.h>
#include <linux/version.h>
#include <linux/of_reserved_mem.h>
#include <linux/interrupt.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/io.h>
#include "cvi_spinlock.h"
#endif

#define JENC_MANAGE_CLOCK 0

#if JENC_MANAGE_CLOCK
#define JPU_CLK_REG     REG_CLK_ENABLE_REG2
#endif

static uint32_t reg_base = JPU_BASE;

#if JENC_MANAGE_CLOCK
static void jpu_set_clock(CVI_BOOL bEnable);
#endif
static void jpu_set_huffman_table(void);
static void jpu_set_quatization_matrix(void);
static void jpu_encode_header(CVI_U32 width, CVI_U32 height);

#if JENC_MANAGE_CLOCK
static void jpu_set_clock(CVI_BOOL bEnable)
{
	unsigned int val = mmio_read_32(JPU_CLK_REG);

	if (bEnable) {
		val |= 0x3300;     // set bits 8, 9, 12, 13
	} else {
		val &= 0xFFFFCCFF; // clr bits 8, 9, 12, 13
	}

	mmio_write_32(JPU_CLK_REG, val);
	//printf("[jenc](r) 0x%x: 0x%x\n", JPU_CLK_REG, mmio_read_32(JPU_CLK_REG));
	printf("[jenc] clock %s\n", bEnable ? "on" : "off");
}
#endif

static void jpu_set_huffman_table(void)
{
	mmio_write_32(reg_base + 0x80, 0x3);
	mmio_write_32(reg_base + 0x88, 0x3000a);
	mmio_write_32(reg_base + 0x88, 0x10000);
	mmio_write_32(reg_base + 0x88, 0x10001);
	mmio_write_32(reg_base + 0x88, 0x20004);
	mmio_write_32(reg_base + 0x88, 0x3000b);
	mmio_write_32(reg_base + 0x88, 0x4001a);
	mmio_write_32(reg_base + 0x88, 0x60078);
	mmio_write_32(reg_base + 0x88, 0x700f8);
	mmio_write_32(reg_base + 0x88, 0x903f6);
	mmio_write_32(reg_base + 0x88, 0xfff82);
	mmio_write_32(reg_base + 0x88, 0xfff83);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x3000c);
	mmio_write_32(reg_base + 0x88, 0x4001b);
	mmio_write_32(reg_base + 0x88, 0x60079);
	mmio_write_32(reg_base + 0x88, 0x801f6);
	mmio_write_32(reg_base + 0x88, 0xa07f6);
	mmio_write_32(reg_base + 0x88, 0xfff84);
	mmio_write_32(reg_base + 0x88, 0xfff85);
	mmio_write_32(reg_base + 0x88, 0xfff86);
	mmio_write_32(reg_base + 0x88, 0xfff87);
	mmio_write_32(reg_base + 0x88, 0xfff88);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x4001c);
	mmio_write_32(reg_base + 0x88, 0x700f9);
	mmio_write_32(reg_base + 0x88, 0x903f7);
	mmio_write_32(reg_base + 0x88, 0xb0ff4);
	mmio_write_32(reg_base + 0x88, 0xfff89);
	mmio_write_32(reg_base + 0x88, 0xfff8a);
	mmio_write_32(reg_base + 0x88, 0xfff8b);
	mmio_write_32(reg_base + 0x88, 0xfff8c);
	mmio_write_32(reg_base + 0x88, 0xfff8d);
	mmio_write_32(reg_base + 0x88, 0xfff8e);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x5003a);
	mmio_write_32(reg_base + 0x88, 0x801f7);
	mmio_write_32(reg_base + 0x88, 0xb0ff5);
	mmio_write_32(reg_base + 0x88, 0xfff8f);
	mmio_write_32(reg_base + 0x88, 0xfff90);
	mmio_write_32(reg_base + 0x88, 0xfff91);
	mmio_write_32(reg_base + 0x88, 0xfff92);
	mmio_write_32(reg_base + 0x88, 0xfff93);
	mmio_write_32(reg_base + 0x88, 0xfff94);
	mmio_write_32(reg_base + 0x88, 0xfff95);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x5003b);
	mmio_write_32(reg_base + 0x88, 0x903f8);
	mmio_write_32(reg_base + 0x88, 0xfff96);
	mmio_write_32(reg_base + 0x88, 0xfff97);
	mmio_write_32(reg_base + 0x88, 0xfff98);
	mmio_write_32(reg_base + 0x88, 0xfff99);
	mmio_write_32(reg_base + 0x88, 0xfff9a);
	mmio_write_32(reg_base + 0x88, 0xfff9b);
	mmio_write_32(reg_base + 0x88, 0xfff9c);
	mmio_write_32(reg_base + 0x88, 0xfff9d);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x6007a);
	mmio_write_32(reg_base + 0x88, 0xa07f7);
	mmio_write_32(reg_base + 0x88, 0xfff9e);
	mmio_write_32(reg_base + 0x88, 0xfff9f);
	mmio_write_32(reg_base + 0x88, 0xfffa0);
	mmio_write_32(reg_base + 0x88, 0xfffa1);
	mmio_write_32(reg_base + 0x88, 0xfffa2);
	mmio_write_32(reg_base + 0x88, 0xfffa3);
	mmio_write_32(reg_base + 0x88, 0xfffa4);
	mmio_write_32(reg_base + 0x88, 0xfffa5);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x6007b);
	mmio_write_32(reg_base + 0x88, 0xb0ff6);
	mmio_write_32(reg_base + 0x88, 0xfffa6);
	mmio_write_32(reg_base + 0x88, 0xfffa7);
	mmio_write_32(reg_base + 0x88, 0xfffa8);
	mmio_write_32(reg_base + 0x88, 0xfffa9);
	mmio_write_32(reg_base + 0x88, 0xfffaa);
	mmio_write_32(reg_base + 0x88, 0xfffab);
	mmio_write_32(reg_base + 0x88, 0xfffac);
	mmio_write_32(reg_base + 0x88, 0xfffad);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x700fa);
	mmio_write_32(reg_base + 0x88, 0xb0ff7);
	mmio_write_32(reg_base + 0x88, 0xfffae);
	mmio_write_32(reg_base + 0x88, 0xfffaf);
	mmio_write_32(reg_base + 0x88, 0xfffb0);
	mmio_write_32(reg_base + 0x88, 0xfffb1);
	mmio_write_32(reg_base + 0x88, 0xfffb2);
	mmio_write_32(reg_base + 0x88, 0xfffb3);
	mmio_write_32(reg_base + 0x88, 0xfffb4);
	mmio_write_32(reg_base + 0x88, 0xfffb5);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x801f8);
	mmio_write_32(reg_base + 0x88, 0xe7fc0);
	mmio_write_32(reg_base + 0x88, 0xfffb6);
	mmio_write_32(reg_base + 0x88, 0xfffb7);
	mmio_write_32(reg_base + 0x88, 0xfffb8);
	mmio_write_32(reg_base + 0x88, 0xfffb9);
	mmio_write_32(reg_base + 0x88, 0xfffba);
	mmio_write_32(reg_base + 0x88, 0xfffbb);
	mmio_write_32(reg_base + 0x88, 0xfffbc);
	mmio_write_32(reg_base + 0x88, 0xfffbd);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x801f9);
	mmio_write_32(reg_base + 0x88, 0xfffbe);
	mmio_write_32(reg_base + 0x88, 0xfffbf);
	mmio_write_32(reg_base + 0x88, 0xfffc0);
	mmio_write_32(reg_base + 0x88, 0xfffc1);
	mmio_write_32(reg_base + 0x88, 0xfffc2);
	mmio_write_32(reg_base + 0x88, 0xfffc3);
	mmio_write_32(reg_base + 0x88, 0xfffc4);
	mmio_write_32(reg_base + 0x88, 0xfffc5);
	mmio_write_32(reg_base + 0x88, 0xfffc6);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x801fa);
	mmio_write_32(reg_base + 0x88, 0xfffc7);
	mmio_write_32(reg_base + 0x88, 0xfffc8);
	mmio_write_32(reg_base + 0x88, 0xfffc9);
	mmio_write_32(reg_base + 0x88, 0xfffca);
	mmio_write_32(reg_base + 0x88, 0xfffcb);
	mmio_write_32(reg_base + 0x88, 0xfffcc);
	mmio_write_32(reg_base + 0x88, 0xfffcd);
	mmio_write_32(reg_base + 0x88, 0xfffce);
	mmio_write_32(reg_base + 0x88, 0xfffcf);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x903f9);
	mmio_write_32(reg_base + 0x88, 0xfffd0);
	mmio_write_32(reg_base + 0x88, 0xfffd1);
	mmio_write_32(reg_base + 0x88, 0xfffd2);
	mmio_write_32(reg_base + 0x88, 0xfffd3);
	mmio_write_32(reg_base + 0x88, 0xfffd4);
	mmio_write_32(reg_base + 0x88, 0xfffd5);
	mmio_write_32(reg_base + 0x88, 0xfffd6);
	mmio_write_32(reg_base + 0x88, 0xfffd7);
	mmio_write_32(reg_base + 0x88, 0xfffd8);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x903fa);
	mmio_write_32(reg_base + 0x88, 0xfffd9);
	mmio_write_32(reg_base + 0x88, 0xfffda);
	mmio_write_32(reg_base + 0x88, 0xfffdb);
	mmio_write_32(reg_base + 0x88, 0xfffdc);
	mmio_write_32(reg_base + 0x88, 0xfffdd);
	mmio_write_32(reg_base + 0x88, 0xfffde);
	mmio_write_32(reg_base + 0x88, 0xfffdf);
	mmio_write_32(reg_base + 0x88, 0xfffe0);
	mmio_write_32(reg_base + 0x88, 0xfffe1);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0xa07f8);
	mmio_write_32(reg_base + 0x88, 0xfffe2);
	mmio_write_32(reg_base + 0x88, 0xfffe3);
	mmio_write_32(reg_base + 0x88, 0xfffe4);
	mmio_write_32(reg_base + 0x88, 0xfffe5);
	mmio_write_32(reg_base + 0x88, 0xfffe6);
	mmio_write_32(reg_base + 0x88, 0xfffe7);
	mmio_write_32(reg_base + 0x88, 0xfffe8);
	mmio_write_32(reg_base + 0x88, 0xfffe9);
	mmio_write_32(reg_base + 0x88, 0xfffea);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0xfffeb);
	mmio_write_32(reg_base + 0x88, 0xfffec);
	mmio_write_32(reg_base + 0x88, 0xfffed);
	mmio_write_32(reg_base + 0x88, 0xfffee);
	mmio_write_32(reg_base + 0x88, 0xfffef);
	mmio_write_32(reg_base + 0x88, 0xffff0);
	mmio_write_32(reg_base + 0x88, 0xffff1);
	mmio_write_32(reg_base + 0x88, 0xffff2);
	mmio_write_32(reg_base + 0x88, 0xffff3);
	mmio_write_32(reg_base + 0x88, 0xffff4);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0xa07f9);
	mmio_write_32(reg_base + 0x88, 0xffff5);
	mmio_write_32(reg_base + 0x88, 0xffff6);
	mmio_write_32(reg_base + 0x88, 0xffff7);
	mmio_write_32(reg_base + 0x88, 0xffff8);
	mmio_write_32(reg_base + 0x88, 0xffff9);
	mmio_write_32(reg_base + 0x88, 0xffffa);
	mmio_write_32(reg_base + 0x88, 0xffffb);
	mmio_write_32(reg_base + 0x88, 0xffffc);
	mmio_write_32(reg_base + 0x88, 0xffffd);
	mmio_write_32(reg_base + 0x88, 0xffffe);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x10000);
	mmio_write_32(reg_base + 0x88, 0x10001);
	mmio_write_32(reg_base + 0x88, 0x20004);
	mmio_write_32(reg_base + 0x88, 0x3000a);
	mmio_write_32(reg_base + 0x88, 0x40018);
	mmio_write_32(reg_base + 0x88, 0x40019);
	mmio_write_32(reg_base + 0x88, 0x50038);
	mmio_write_32(reg_base + 0x88, 0x60078);
	mmio_write_32(reg_base + 0x88, 0x801f4);
	mmio_write_32(reg_base + 0x88, 0x903f6);
	mmio_write_32(reg_base + 0x88, 0xb0ff4);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x3000b);
	mmio_write_32(reg_base + 0x88, 0x50039);
	mmio_write_32(reg_base + 0x88, 0x700f6);
	mmio_write_32(reg_base + 0x88, 0x801f5);
	mmio_write_32(reg_base + 0x88, 0xa07f6);
	mmio_write_32(reg_base + 0x88, 0xb0ff5);
	mmio_write_32(reg_base + 0x88, 0xfff88);
	mmio_write_32(reg_base + 0x88, 0xfff89);
	mmio_write_32(reg_base + 0x88, 0xfff8a);
	mmio_write_32(reg_base + 0x88, 0xfff8b);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x4001a);
	mmio_write_32(reg_base + 0x88, 0x700f7);
	mmio_write_32(reg_base + 0x88, 0x903f7);
	mmio_write_32(reg_base + 0x88, 0xb0ff6);
	mmio_write_32(reg_base + 0x88, 0xe7fc2);
	mmio_write_32(reg_base + 0x88, 0xfff8c);
	mmio_write_32(reg_base + 0x88, 0xfff8d);
	mmio_write_32(reg_base + 0x88, 0xfff8e);
	mmio_write_32(reg_base + 0x88, 0xfff8f);
	mmio_write_32(reg_base + 0x88, 0xfff90);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x4001b);
	mmio_write_32(reg_base + 0x88, 0x700f8);
	mmio_write_32(reg_base + 0x88, 0x903f8);
	mmio_write_32(reg_base + 0x88, 0xb0ff7);
	mmio_write_32(reg_base + 0x88, 0xfff91);
	mmio_write_32(reg_base + 0x88, 0xfff92);
	mmio_write_32(reg_base + 0x88, 0xfff93);
	mmio_write_32(reg_base + 0x88, 0xfff94);
	mmio_write_32(reg_base + 0x88, 0xfff95);
	mmio_write_32(reg_base + 0x88, 0xfff96);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x5003a);
	mmio_write_32(reg_base + 0x88, 0x801f6);
	mmio_write_32(reg_base + 0x88, 0xfff97);
	mmio_write_32(reg_base + 0x88, 0xfff98);
	mmio_write_32(reg_base + 0x88, 0xfff99);
	mmio_write_32(reg_base + 0x88, 0xfff9a);
	mmio_write_32(reg_base + 0x88, 0xfff9b);
	mmio_write_32(reg_base + 0x88, 0xfff9c);
	mmio_write_32(reg_base + 0x88, 0xfff9d);
	mmio_write_32(reg_base + 0x88, 0xfff9e);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x5003b);
	mmio_write_32(reg_base + 0x88, 0x903f9);
	mmio_write_32(reg_base + 0x88, 0xfff9f);
	mmio_write_32(reg_base + 0x88, 0xfffa0);
	mmio_write_32(reg_base + 0x88, 0xfffa1);
	mmio_write_32(reg_base + 0x88, 0xfffa2);
	mmio_write_32(reg_base + 0x88, 0xfffa3);
	mmio_write_32(reg_base + 0x88, 0xfffa4);
	mmio_write_32(reg_base + 0x88, 0xfffa5);
	mmio_write_32(reg_base + 0x88, 0xfffa6);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x60079);
	mmio_write_32(reg_base + 0x88, 0xa07f7);
	mmio_write_32(reg_base + 0x88, 0xfffa7);
	mmio_write_32(reg_base + 0x88, 0xfffa8);
	mmio_write_32(reg_base + 0x88, 0xfffa9);
	mmio_write_32(reg_base + 0x88, 0xfffaa);
	mmio_write_32(reg_base + 0x88, 0xfffab);
	mmio_write_32(reg_base + 0x88, 0xfffac);
	mmio_write_32(reg_base + 0x88, 0xfffad);
	mmio_write_32(reg_base + 0x88, 0xfffae);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x6007a);
	mmio_write_32(reg_base + 0x88, 0xa07f8);
	mmio_write_32(reg_base + 0x88, 0xfffaf);
	mmio_write_32(reg_base + 0x88, 0xfffb0);
	mmio_write_32(reg_base + 0x88, 0xfffb1);
	mmio_write_32(reg_base + 0x88, 0xfffb2);
	mmio_write_32(reg_base + 0x88, 0xfffb3);
	mmio_write_32(reg_base + 0x88, 0xfffb4);
	mmio_write_32(reg_base + 0x88, 0xfffb5);
	mmio_write_32(reg_base + 0x88, 0xfffb6);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x700f9);
	mmio_write_32(reg_base + 0x88, 0xfffb7);
	mmio_write_32(reg_base + 0x88, 0xfffb8);
	mmio_write_32(reg_base + 0x88, 0xfffb9);
	mmio_write_32(reg_base + 0x88, 0xfffba);
	mmio_write_32(reg_base + 0x88, 0xfffbb);
	mmio_write_32(reg_base + 0x88, 0xfffbc);
	mmio_write_32(reg_base + 0x88, 0xfffbd);
	mmio_write_32(reg_base + 0x88, 0xfffbe);
	mmio_write_32(reg_base + 0x88, 0xfffbf);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x801f7);
	mmio_write_32(reg_base + 0x88, 0xfffc0);
	mmio_write_32(reg_base + 0x88, 0xfffc1);
	mmio_write_32(reg_base + 0x88, 0xfffc2);
	mmio_write_32(reg_base + 0x88, 0xfffc3);
	mmio_write_32(reg_base + 0x88, 0xfffc4);
	mmio_write_32(reg_base + 0x88, 0xfffc5);
	mmio_write_32(reg_base + 0x88, 0xfffc6);
	mmio_write_32(reg_base + 0x88, 0xfffc7);
	mmio_write_32(reg_base + 0x88, 0xfffc8);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x801f8);
	mmio_write_32(reg_base + 0x88, 0xfffc9);
	mmio_write_32(reg_base + 0x88, 0xfffca);
	mmio_write_32(reg_base + 0x88, 0xfffcb);
	mmio_write_32(reg_base + 0x88, 0xfffcc);
	mmio_write_32(reg_base + 0x88, 0xfffcd);
	mmio_write_32(reg_base + 0x88, 0xfffce);
	mmio_write_32(reg_base + 0x88, 0xfffcf);
	mmio_write_32(reg_base + 0x88, 0xfffd0);
	mmio_write_32(reg_base + 0x88, 0xfffd1);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x801f9);
	mmio_write_32(reg_base + 0x88, 0xfffd2);
	mmio_write_32(reg_base + 0x88, 0xfffd3);
	mmio_write_32(reg_base + 0x88, 0xfffd4);
	mmio_write_32(reg_base + 0x88, 0xfffd5);
	mmio_write_32(reg_base + 0x88, 0xfffd6);
	mmio_write_32(reg_base + 0x88, 0xfffd7);
	mmio_write_32(reg_base + 0x88, 0xfffd8);
	mmio_write_32(reg_base + 0x88, 0xfffd9);
	mmio_write_32(reg_base + 0x88, 0xfffda);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x801fa);
	mmio_write_32(reg_base + 0x88, 0xfffdb);
	mmio_write_32(reg_base + 0x88, 0xfffdc);
	mmio_write_32(reg_base + 0x88, 0xfffdd);
	mmio_write_32(reg_base + 0x88, 0xfffde);
	mmio_write_32(reg_base + 0x88, 0xfffdf);
	mmio_write_32(reg_base + 0x88, 0xfffe0);
	mmio_write_32(reg_base + 0x88, 0xfffe1);
	mmio_write_32(reg_base + 0x88, 0xfffe2);
	mmio_write_32(reg_base + 0x88, 0xfffe3);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0xa07f9);
	mmio_write_32(reg_base + 0x88, 0xfffe4);
	mmio_write_32(reg_base + 0x88, 0xfffe5);
	mmio_write_32(reg_base + 0x88, 0xfffe6);
	mmio_write_32(reg_base + 0x88, 0xfffe7);
	mmio_write_32(reg_base + 0x88, 0xfffe8);
	mmio_write_32(reg_base + 0x88, 0xfffe9);
	mmio_write_32(reg_base + 0x88, 0xfffea);
	mmio_write_32(reg_base + 0x88, 0xfffeb);
	mmio_write_32(reg_base + 0x88, 0xfffec);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0xd3fe0);
	mmio_write_32(reg_base + 0x88, 0xfffed);
	mmio_write_32(reg_base + 0x88, 0xfffee);
	mmio_write_32(reg_base + 0x88, 0xfffef);
	mmio_write_32(reg_base + 0x88, 0xffff0);
	mmio_write_32(reg_base + 0x88, 0xffff1);
	mmio_write_32(reg_base + 0x88, 0xffff2);
	mmio_write_32(reg_base + 0x88, 0xffff3);
	mmio_write_32(reg_base + 0x88, 0xffff4);
	mmio_write_32(reg_base + 0x88, 0xffff5);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x903fa);
	mmio_write_32(reg_base + 0x88, 0xe7fc3);
	mmio_write_32(reg_base + 0x88, 0xffff6);
	mmio_write_32(reg_base + 0x88, 0xffff7);
	mmio_write_32(reg_base + 0x88, 0xffff8);
	mmio_write_32(reg_base + 0x88, 0xffff9);
	mmio_write_32(reg_base + 0x88, 0xffffa);
	mmio_write_32(reg_base + 0x88, 0xffffb);
	mmio_write_32(reg_base + 0x88, 0xffffc);
	mmio_write_32(reg_base + 0x88, 0xffffd);
	mmio_write_32(reg_base + 0x88, 0xffffe);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x10000);
	mmio_write_32(reg_base + 0x88, 0x20002);
	mmio_write_32(reg_base + 0x88, 0x20003);
	mmio_write_32(reg_base + 0x88, 0x20004);
	mmio_write_32(reg_base + 0x88, 0x20005);
	mmio_write_32(reg_base + 0x88, 0x20006);
	mmio_write_32(reg_base + 0x88, 0x3000e);
	mmio_write_32(reg_base + 0x88, 0x4001e);
	mmio_write_32(reg_base + 0x88, 0x5003e);
	mmio_write_32(reg_base + 0x88, 0x6007e);
	mmio_write_32(reg_base + 0x88, 0x700fe);
	mmio_write_32(reg_base + 0x88, 0x801fe);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x10000);
	mmio_write_32(reg_base + 0x88, 0x10001);
	mmio_write_32(reg_base + 0x88, 0x10002);
	mmio_write_32(reg_base + 0x88, 0x20006);
	mmio_write_32(reg_base + 0x88, 0x3000e);
	mmio_write_32(reg_base + 0x88, 0x4001e);
	mmio_write_32(reg_base + 0x88, 0x5003e);
	mmio_write_32(reg_base + 0x88, 0x6007e);
	mmio_write_32(reg_base + 0x88, 0x700fe);
	mmio_write_32(reg_base + 0x88, 0x801fe);
	mmio_write_32(reg_base + 0x88, 0x903fe);
	mmio_write_32(reg_base + 0x88, 0xa07fe);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x88, 0x0);
	mmio_write_32(reg_base + 0x80, 0x0);
}

static void jpu_set_quatization_matrix(void)
{
	mmio_write_32(reg_base + 0x90, 0x3);
	mmio_write_32(reg_base + 0x98, 0x615555);
	mmio_write_32(reg_base + 0x98, 0x420000);
	mmio_write_32(reg_base + 0x98, 0x420000);
	mmio_write_32(reg_base + 0x98, 0x420000);
	mmio_write_32(reg_base + 0x98, 0x519999);
	mmio_write_32(reg_base + 0x98, 0x420000);
	mmio_write_32(reg_base + 0x98, 0x615555);
	mmio_write_32(reg_base + 0x98, 0x519999);
	mmio_write_32(reg_base + 0x98, 0x519999);
	mmio_write_32(reg_base + 0x98, 0x615555);
	mmio_write_32(reg_base + 0x98, 0x90e38e);
	mmio_write_32(reg_base + 0x98, 0x615555);
	mmio_write_32(reg_base + 0x98, 0x519999);
	mmio_write_32(reg_base + 0x98, 0x615555);
	mmio_write_32(reg_base + 0x98, 0x90e38e);
	mmio_write_32(reg_base + 0x98, 0xb0ba2e);
	mmio_write_32(reg_base + 0x98, 0x810000);
	mmio_write_32(reg_base + 0x98, 0x615555);
	mmio_write_32(reg_base + 0x98, 0x615555);
	mmio_write_32(reg_base + 0x98, 0x810000);
	mmio_write_32(reg_base + 0x98, 0xb0ba2e);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xa0cccc);
	mmio_write_32(reg_base + 0x98, 0xa0cccc);
	mmio_write_32(reg_base + 0x98, 0xb0ba2e);
	mmio_write_32(reg_base + 0x98, 0xa0cccc);
	mmio_write_32(reg_base + 0x98, 0xa0cccc);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0x1008000);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0x1008000);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x90, 0x0);
	mmio_write_32(reg_base + 0x90, 0x43);
	mmio_write_32(reg_base + 0x98, 0x712492);
	mmio_write_32(reg_base + 0x98, 0x712492);
	mmio_write_32(reg_base + 0x98, 0x712492);
	mmio_write_32(reg_base + 0x98, 0xd09d89);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xd09d89);
	mmio_write_32(reg_base + 0x98, 0x1805555);
	mmio_write_32(reg_base + 0x98, 0x1008000);
	mmio_write_32(reg_base + 0x98, 0x1008000);
	mmio_write_32(reg_base + 0x98, 0x1805555);
	mmio_write_32(reg_base + 0x98, 0x1406666);
	mmio_write_32(reg_base + 0x98, 0xe09249);
	mmio_write_32(reg_base + 0x98, 0xe09249);
	mmio_write_32(reg_base + 0x98, 0xe09249);
	mmio_write_32(reg_base + 0x98, 0x1406666);
	mmio_write_32(reg_base + 0x98, 0x1406666);
	mmio_write_32(reg_base + 0x98, 0xe09249);
	mmio_write_32(reg_base + 0x98, 0xe09249);
	mmio_write_32(reg_base + 0x98, 0xe09249);
	mmio_write_32(reg_base + 0x98, 0xe09249);
	mmio_write_32(reg_base + 0x98, 0x1406666);
	mmio_write_32(reg_base + 0x98, 0x1107878);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0x1107878);
	mmio_write_32(reg_base + 0x98, 0x1107878);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0x1107878);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x90, 0x40);
	mmio_write_32(reg_base + 0x90, 0x83);
	mmio_write_32(reg_base + 0x98, 0x712492);
	mmio_write_32(reg_base + 0x98, 0x712492);
	mmio_write_32(reg_base + 0x98, 0x712492);
	mmio_write_32(reg_base + 0x98, 0xd09d89);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xd09d89);
	mmio_write_32(reg_base + 0x98, 0x1805555);
	mmio_write_32(reg_base + 0x98, 0x1008000);
	mmio_write_32(reg_base + 0x98, 0x1008000);
	mmio_write_32(reg_base + 0x98, 0x1805555);
	mmio_write_32(reg_base + 0x98, 0x1406666);
	mmio_write_32(reg_base + 0x98, 0xe09249);
	mmio_write_32(reg_base + 0x98, 0xe09249);
	mmio_write_32(reg_base + 0x98, 0xe09249);
	mmio_write_32(reg_base + 0x98, 0x1406666);
	mmio_write_32(reg_base + 0x98, 0x1406666);
	mmio_write_32(reg_base + 0x98, 0xe09249);
	mmio_write_32(reg_base + 0x98, 0xe09249);
	mmio_write_32(reg_base + 0x98, 0xe09249);
	mmio_write_32(reg_base + 0x98, 0xe09249);
	mmio_write_32(reg_base + 0x98, 0x1406666);
	mmio_write_32(reg_base + 0x98, 0x1107878);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0x1107878);
	mmio_write_32(reg_base + 0x98, 0x1107878);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0x1107878);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x98, 0xc0aaaa);
	mmio_write_32(reg_base + 0x90, 0x80);
}

static void jpu_encode_header(CVI_U32 width, CVI_U32 height)
{
	mmio_write_32(reg_base + 0x124, 0xffd8);
	mmio_write_32(reg_base + 0x12c, 0xffe90004);
	mmio_write_32(reg_base + 0x124, 0x0);
	mmio_write_32(reg_base + 0x124, 0xffdb);
	mmio_write_32(reg_base + 0x128, 0x4300);
	mmio_write_32(reg_base + 0x12c, 0x6040404);
	mmio_write_32(reg_base + 0x12c, 0x5040605);
	mmio_write_32(reg_base + 0x12c, 0x5060906);
	mmio_write_32(reg_base + 0x12c, 0x506090b);
	mmio_write_32(reg_base + 0x12c, 0x8060608);
	mmio_write_32(reg_base + 0x12c, 0xb0c0a0a);
	mmio_write_32(reg_base + 0x12c, 0xb0a0a0c);
	mmio_write_32(reg_base + 0x12c, 0x100c0c0c);
	mmio_write_32(reg_base + 0x12c, 0xc0c0c10);
	mmio_write_32(reg_base + 0x12c, 0xc0c0c0c);
	mmio_write_32(reg_base + 0x12c, 0xc0c0c0c);
	mmio_write_32(reg_base + 0x12c, 0xc0c0c0c);
	mmio_write_32(reg_base + 0x12c, 0xc0c0c0c);
	mmio_write_32(reg_base + 0x12c, 0xc0c0c0c);
	mmio_write_32(reg_base + 0x12c, 0xc0c0c0c);
	mmio_write_32(reg_base + 0x12c, 0xc0c0c0c);
	mmio_write_32(reg_base + 0x12c, 0xffdb0043);
	mmio_write_32(reg_base + 0x120, 0x1);
	mmio_write_32(reg_base + 0x12c, 0x707070d);
	mmio_write_32(reg_base + 0x12c, 0xc0d1810);
	mmio_write_32(reg_base + 0x12c, 0x1018140e);
	mmio_write_32(reg_base + 0x12c, 0xe0e1414);
	mmio_write_32(reg_base + 0x12c, 0xe0e0e0e);
	mmio_write_32(reg_base + 0x12c, 0x14110c0c);
	mmio_write_32(reg_base + 0x12c, 0xc0c0c11);
	mmio_write_32(reg_base + 0x12c, 0x110c0c0c);
	mmio_write_32(reg_base + 0x12c, 0xc0c0c11);
	mmio_write_32(reg_base + 0x12c, 0xc0c0c0c);
	mmio_write_32(reg_base + 0x12c, 0xc0c0c0c);
	mmio_write_32(reg_base + 0x12c, 0xc0c0c0c);
	mmio_write_32(reg_base + 0x12c, 0xc0c0c0c);
	mmio_write_32(reg_base + 0x12c, 0xc0c0c0c);
	mmio_write_32(reg_base + 0x12c, 0xc0c0c0c);
	mmio_write_32(reg_base + 0x12c, 0xc0c0c0c);
	mmio_write_32(reg_base + 0x124, 0xffc4);
	mmio_write_32(reg_base + 0x128, 0x1f00);
	mmio_write_32(reg_base + 0x12c, 0x10501);
	mmio_write_32(reg_base + 0x12c, 0x1010101);
	mmio_write_32(reg_base + 0x12c, 0x1000000);
	mmio_write_32(reg_base + 0x12c, 0x0);
	mmio_write_32(reg_base + 0x12c, 0x10203);
	mmio_write_32(reg_base + 0x12c, 0x4050607);
	mmio_write_32(reg_base + 0x12c, 0x8090a0b);
	mmio_write_32(reg_base + 0x12c, 0xffc400b5);
	mmio_write_32(reg_base + 0x120, 0x10);
	mmio_write_32(reg_base + 0x12c, 0x20103);
	mmio_write_32(reg_base + 0x12c, 0x3020403);
	mmio_write_32(reg_base + 0x12c, 0x5050404);
	mmio_write_32(reg_base + 0x12c, 0x17d);
	mmio_write_32(reg_base + 0x12c, 0x1020300);
	mmio_write_32(reg_base + 0x12c, 0x4110512);
	mmio_write_32(reg_base + 0x12c, 0x21314106);
	mmio_write_32(reg_base + 0x12c, 0x13516107);
	mmio_write_32(reg_base + 0x12c, 0x22711432);
	mmio_write_32(reg_base + 0x12c, 0x8191a108);
	mmio_write_32(reg_base + 0x12c, 0x2342b1c1);
	mmio_write_32(reg_base + 0x12c, 0x1552d1f0);
	mmio_write_32(reg_base + 0x12c, 0x24336272);
	mmio_write_32(reg_base + 0x12c, 0x82090a16);
	mmio_write_32(reg_base + 0x12c, 0x1718191a);
	mmio_write_32(reg_base + 0x12c, 0x25262728);
	mmio_write_32(reg_base + 0x12c, 0x292a3435);
	mmio_write_32(reg_base + 0x12c, 0x36373839);
	mmio_write_32(reg_base + 0x12c, 0x3a434445);
	mmio_write_32(reg_base + 0x12c, 0x46474849);
	mmio_write_32(reg_base + 0x12c, 0x4a535455);
	mmio_write_32(reg_base + 0x12c, 0x56575859);
	mmio_write_32(reg_base + 0x12c, 0x5a636465);
	mmio_write_32(reg_base + 0x12c, 0x66676869);
	mmio_write_32(reg_base + 0x12c, 0x6a737475);
	mmio_write_32(reg_base + 0x12c, 0x76777879);
	mmio_write_32(reg_base + 0x12c, 0x7a838485);
	mmio_write_32(reg_base + 0x12c, 0x86878889);
	mmio_write_32(reg_base + 0x12c, 0x8a929394);
	mmio_write_32(reg_base + 0x12c, 0x95969798);
	mmio_write_32(reg_base + 0x12c, 0x999aa2a3);
	mmio_write_32(reg_base + 0x12c, 0xa4a5a6a7);
	mmio_write_32(reg_base + 0x12c, 0xa8a9aab2);
	mmio_write_32(reg_base + 0x12c, 0xb3b4b5b6);
	mmio_write_32(reg_base + 0x12c, 0xb7b8b9ba);
	mmio_write_32(reg_base + 0x12c, 0xc2c3c4c5);
	mmio_write_32(reg_base + 0x12c, 0xc6c7c8c9);
	mmio_write_32(reg_base + 0x12c, 0xcad2d3d4);
	mmio_write_32(reg_base + 0x12c, 0xd5d6d7d8);
	mmio_write_32(reg_base + 0x12c, 0xd9dae1e2);
	mmio_write_32(reg_base + 0x12c, 0xe3e4e5e6);
	mmio_write_32(reg_base + 0x12c, 0xe7e8e9ea);
	mmio_write_32(reg_base + 0x12c, 0xf1f2f3f4);
	mmio_write_32(reg_base + 0x12c, 0xf5f6f7f8);
	mmio_write_32(reg_base + 0x124, 0xf9fa);
	mmio_write_32(reg_base + 0x12c, 0xffc4001f);
	mmio_write_32(reg_base + 0x120, 0x1);
	mmio_write_32(reg_base + 0x12c, 0x30101);
	mmio_write_32(reg_base + 0x12c, 0x1010101);
	mmio_write_32(reg_base + 0x12c, 0x1010100);
	mmio_write_32(reg_base + 0x12c, 0x0);
	mmio_write_32(reg_base + 0x12c, 0x10203);
	mmio_write_32(reg_base + 0x12c, 0x4050607);
	mmio_write_32(reg_base + 0x12c, 0x8090a0b);
	mmio_write_32(reg_base + 0x12c, 0xffc400b5);
	mmio_write_32(reg_base + 0x120, 0x11);
	mmio_write_32(reg_base + 0x12c, 0x20102);
	mmio_write_32(reg_base + 0x12c, 0x4040304);
	mmio_write_32(reg_base + 0x12c, 0x7050404);
	mmio_write_32(reg_base + 0x12c, 0x10277);
	mmio_write_32(reg_base + 0x12c, 0x10203);
	mmio_write_32(reg_base + 0x12c, 0x11040521);
	mmio_write_32(reg_base + 0x12c, 0x31061241);
	mmio_write_32(reg_base + 0x12c, 0x51076171);
	mmio_write_32(reg_base + 0x12c, 0x13223281);
	mmio_write_32(reg_base + 0x12c, 0x8144291);
	mmio_write_32(reg_base + 0x12c, 0xa1b1c109);
	mmio_write_32(reg_base + 0x12c, 0x233352f0);
	mmio_write_32(reg_base + 0x12c, 0x156272d1);
	mmio_write_32(reg_base + 0x12c, 0xa162434);
	mmio_write_32(reg_base + 0x12c, 0xe125f117);
	mmio_write_32(reg_base + 0x12c, 0x18191a26);
	mmio_write_32(reg_base + 0x12c, 0x2728292a);
	mmio_write_32(reg_base + 0x12c, 0x35363738);
	mmio_write_32(reg_base + 0x12c, 0x393a4344);
	mmio_write_32(reg_base + 0x12c, 0x45464748);
	mmio_write_32(reg_base + 0x12c, 0x494a5354);
	mmio_write_32(reg_base + 0x12c, 0x55565758);
	mmio_write_32(reg_base + 0x12c, 0x595a6364);
	mmio_write_32(reg_base + 0x12c, 0x65666768);
	mmio_write_32(reg_base + 0x12c, 0x696a7374);
	mmio_write_32(reg_base + 0x12c, 0x75767778);
	mmio_write_32(reg_base + 0x12c, 0x797a8283);
	mmio_write_32(reg_base + 0x12c, 0x84858687);
	mmio_write_32(reg_base + 0x12c, 0x88898a92);
	mmio_write_32(reg_base + 0x12c, 0x93949596);
	mmio_write_32(reg_base + 0x12c, 0x9798999a);
	mmio_write_32(reg_base + 0x12c, 0xa2a3a4a5);
	mmio_write_32(reg_base + 0x12c, 0xa6a7a8a9);
	mmio_write_32(reg_base + 0x12c, 0xaab2b3b4);
	mmio_write_32(reg_base + 0x12c, 0xb5b6b7b8);
	mmio_write_32(reg_base + 0x12c, 0xb9bac2c3);
	mmio_write_32(reg_base + 0x12c, 0xc4c5c6c7);
	mmio_write_32(reg_base + 0x12c, 0xc8c9cad2);
	mmio_write_32(reg_base + 0x12c, 0xd3d4d5d6);
	mmio_write_32(reg_base + 0x12c, 0xd7d8d9da);
	mmio_write_32(reg_base + 0x12c, 0xe2e3e4e5);
	mmio_write_32(reg_base + 0x12c, 0xe6e7e8e9);
	mmio_write_32(reg_base + 0x12c, 0xeaf2f3f4);
	mmio_write_32(reg_base + 0x12c, 0xf5f6f7f8);
	mmio_write_32(reg_base + 0x124, 0xf9fa);
	mmio_write_32(reg_base + 0x124, 0xffc0);
	mmio_write_32(reg_base + 0x124, 0x11);
	mmio_write_32(reg_base + 0x120, 0x8);
	mmio_write_32(reg_base + 0x12c, height << 16 | width);
	mmio_write_32(reg_base + 0x120, 0x3);
	mmio_write_32(reg_base + 0x120, 0x1);
	mmio_write_32(reg_base + 0x120, 0x22);
	mmio_write_32(reg_base + 0x120, 0x0);
	mmio_write_32(reg_base + 0x120, 0x2);
	mmio_write_32(reg_base + 0x120, 0x11);
	mmio_write_32(reg_base + 0x120, 0x1);
	mmio_write_32(reg_base + 0x120, 0x3);
	mmio_write_32(reg_base + 0x120, 0x11);
	mmio_write_32(reg_base + 0x120, 0x1);
}

int jpu_enc(CVI_U32 width, CVI_U32 height, CVI_U32 phySrcAddr, CVI_U32 phyDstAddr, CVI_U64 pts)
{
	CVI_U32 val = 0x0;
	CVI_U32 alignedWidth = ((width + 15) >> 4) << 4;
	CVI_U32 alignedHeight = ((height + 15) >> 4) << 4;
	CVI_U32 stride = width;
	CVI_U32 srcY = phySrcAddr;
	CVI_U32 srcCb = phySrcAddr + stride * height;
	CVI_U32 wrPtr;

	printf("[jenc] %dx%d, pts 0x%lld,  srcBuf 0x%x, outBuf 0x%x\n", width, height, pts, phySrcAddr, phyDstAddr);

#if JENC_MANAGE_CLOCK
	jpu_set_clock(CVI_TRUE);
#endif

	mmio_write_32(reg_base + 0x0, 0x2);
	mmio_write_32(reg_base + 0x230, 0x0);
	mmio_write_32(reg_base + 0x208, 0x0);
	mmio_write_32(reg_base + 0x210, 0x0);
	mmio_write_32(reg_base + 0x20c, 0x0);

	mmio_write_32(reg_base + 0x20c, phyDstAddr);
	mmio_write_32(reg_base + 0x210, phyDstAddr);
	mmio_write_32(reg_base + 0x28, 0x0);
	mmio_write_32(reg_base + 0x230, phyDstAddr);
	mmio_write_32(reg_base + 0x208, srcY);
	mmio_write_32(reg_base + 0x22c, 0x0);
	mmio_write_32(reg_base + 0x21c, 0x40);
	mmio_write_32(reg_base + 0x214, srcY);
	mmio_write_32(reg_base + 0x218, 0x0);
	mmio_write_32(reg_base + 0x110, 0x0);
	mmio_write_32(reg_base + 0x114, 0x0);
	mmio_write_32(reg_base + 0x140, 0x0);
	mmio_write_32(reg_base + 0x100, 0x0);
	mmio_write_32(reg_base + 0x144, 0x7f);
	mmio_write_32(reg_base + 0x148, 0x40);
	mmio_write_32(reg_base + 0x14c, 0x40);
	mmio_write_32(reg_base + 0x10, 0x18);
	mmio_write_32(reg_base + 0x20, 0x0);
	mmio_write_32(reg_base + 0x30, 0x3); // yuv420p: 0x0, nv21: 0x3
	mmio_write_32(reg_base + 0xb0, 0x0);
	mmio_write_32(reg_base + 0x228, 0x1);
	mmio_write_32(reg_base + 0x2c, 0x8ac000a);

	jpu_set_huffman_table();
	jpu_set_quatization_matrix();
	jpu_encode_header(width, height);

	mmio_write_32(reg_base + 0x14, alignedWidth << 16 | alignedHeight);
	mmio_write_32(reg_base + 0x1c, 0x0);
	mmio_write_32(reg_base + 0x18, 0x63a55);
	mmio_write_32(reg_base + 0x100, 0x0);
	mmio_write_32(reg_base + 0x34, srcY);
	mmio_write_32(reg_base + 0x38, srcCb);
	mmio_write_32(reg_base + 0x3c, 0x0);    // yuv420p: srcCr
	mmio_write_32(reg_base + 0x64, stride);
	mmio_write_32(reg_base + 0x68, stride); // yuv420p: strideC
	mmio_write_32(reg_base + 0x4, 0x0);
	mmio_write_32(reg_base + 0x0, 0x1);     // fire

	while (!(val & 0x1)) {
		val = mmio_read_32(reg_base + 0x4);
		//printf("[jenc] read 0x4: 0x%x\n", val);
	}
	//printf("[jenc] encode done\n");

	mmio_write_32(reg_base + 0x4, 0x1);     // clear encode done status
	mmio_write_32(reg_base + 0x238, 0x0);   // flush

	// get encoded bitstream info
	wrPtr = mmio_read_32(reg_base + 0x20C);
#if JENC_MANAGE_CLOCK
	jpu_set_clock(CVI_FALSE);
#endif
	return (int)(wrPtr - phyDstAddr);
}
